import enum
import hashlib

from marshmallow import fields, validates_schema, ValidationError, post_load

from gis.common.django_ext.forms import BaseSchema
from itpay.core.conf import IMConf
from itpay.core.mch import service as mch_service


class SignRequestSchema(BaseSchema):
    """
    统一签名参数处理基类。
    """

    timestamp = fields.Integer(required=True)
    sign = fields.String(required=True)

    def get_key(self, data):
        raise NotImplementedError("must implement in subclass")

    @validates_schema
    def check_sign(self, data):
        c_data = data.copy()
        sign = c_data.pop("sign")
        s = ""
        for k in sorted(c_data.keys()):
            rs = c_data[k]
            if (
                c_data[k]
                and isinstance(c_data[k], list)
                and isinstance(c_data[k][0], enum.Enum)
            ):
                rs = [e.value for e in c_data[k]]
            if c_data[k] and isinstance(c_data[k], enum.Enum):
                rs = c_data[k].value
            s += "{}={}&".format(k, rs)
        s += "key=%s" % self.get_key(data)
        m = hashlib.md5()
        m.update(s.encode("utf8"))
        if sign.upper() != m.hexdigest().upper():
            raise ValidationError("the sign is error")

    @post_load
    def remove_sign_params(self, data):
        del data["timestamp"]
        del data["sign"]
        return data


class MchSignRequestSchema(SignRequestSchema):
    """
    商户接入接口签名授权
    """

    mch_id = fields.Integer(required=True)

    def get_key(self, data):
        mch = mch_service.get_mch(data["mch_id"], exclude_api_key=False)
        return mch["api_key"]


class IMSignRequestSchema(SignRequestSchema):
    """
    IM Server 调用签名，走单独的key分配
    """

    def get_key(self, data):
        return IMConf.api_key
